package main

import (
	"fmt"
	"github.com/Unknwon/goconfig"
	"math/rand"
	"net/http"
	"net/http/httputil"
	"net/url"
	"sort"
)

var p = fmt.Println

var ini iniType

func main() {
	ini = intInit()
	http.HandleFunc("/", handerAll)
	binding := ":" + ini.port
	p("goproxy started on port :", binding)
	err := http.ListenAndServe(binding, nil)
	if err != nil {
		p("[ERROR] ERROR: ", err)
		return
	}
}

func handerAll(respWriter http.ResponseWriter, req *http.Request) {
	fmt.Print("*")
	defer req.Body.Close()
	
	respWriter.Header().Set("goproxy", "wkc_go_proxy")
	director := func(req *http.Request) {}
	proxy := getTransportFieldURL()

	reverseProxy := httputil.ReverseProxy{Director: director,
		Transport:     proxy,
		FlushInterval: 100000000,
	}
	reverseProxy.ServeHTTP(respWriter, req)

	if err := recover(); err != nil {
		p("*********unknow error*********")
		p(err)
		p("\n\n\n")
	}
}

func getTransportFieldURL() (transport *http.Transport) {
	url_i := url.URL{}
	url_proxy, _ := url_i.Parse(randProxy())
	proxy := http.ProxyURL(url_proxy)
	transport = &http.Transport{Proxy: proxy}
	return transport
}


func randProxy() string {
	r := ini.proxy[rand.Int()%len(ini.proxy)]
	//p("proxy ", r)
	return r
}

type iniType struct {
	port      string
	proxy     []string
}


func intInit() iniType {
	var t iniType
	ini, err := goconfig.LoadConfigFile("goproxy.ini")
	if err != nil {
		p(err)
	}

	t.port, err = ini.GetValue("port", "port")
	iProxy, err := ini.GetSection("proxy")
	for _, value := range iProxy {
		t.proxy = append(t.proxy, value)
	}

	sort.Strings(t.proxy)
	p(t.proxy)
	return t
}
